package com.zl.learning.excel;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Description: excel导出工具
 * Date: 2016/10/24 10:17
 */
public class PoiExcelUtil {

    /**
     * excel导出工具
     *
     * @param <E>
     * @param response
     * @param headerData
     * @param list       void
     * @author: bingye
     * @createTime: 2015-4-29 下午06:52:17
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static <E> void exportExcel(HttpServletResponse response, String fileName, Map<String, String> headerData, List<E> list, String dateFormat) {
        SimpleDateFormat format = new SimpleDateFormat(dateFormat);
        //创建工作簿
        HSSFWorkbook wb = new HSSFWorkbook();
        //创建一个sheet
        HSSFSheet sheet = wb.createSheet("Sheet1");

        HSSFRow headerRow = sheet.createRow(0);
        HSSFRow contentRow = null;

        int cellIndex = 0;
        //设置标题
        for (String h : headerData.keySet()) {
            headerRow.createCell(cellIndex).setCellValue(headerData.get(h));
            cellIndex++;
        }

        try {
            for (int i = 0; i < list.size(); i++) {
                contentRow = sheet.createRow(i + 1);
                //获取每一个对象
                E o = list.get(i);
                Class cls = o.getClass();
                cellIndex = 0;
                for (String h : headerData.keySet()) {
                    if (h.contains(".")) {
                        String[] newCls = h.split("\\.");
                        String clsName = newCls[0].substring(0, 1).toUpperCase() + newCls[0].substring(1);
                        Method clsMethod = cls.getMethod("get" + clsName);
                        Object value = clsMethod.invoke(o);
                        Class subClass = value.getClass();
                        if(subClass.getName().toLowerCase().contains("array")){
                            List<Object> objects = (ArrayList)value;
                            Object cellValue="";
                            for(Object object:objects){
                                Class objClass = object.getClass();
                                Object tmpObjValue = objClass.getMethod("get" + newCls[1].substring(0, 1).toUpperCase() + newCls[1].substring(1)).invoke(object);
                                cellValue =tmpObjValue==null?cellValue:cellValue+ tmpObjValue.toString()+",";
                            }
                            if (cellValue != null && cellValue.toString().length()>0) {
                                cellValue = cellValue.toString().substring(0,cellValue.toString().length()-1);
                                contentRow.createCell(cellIndex++).setCellValue(cellValue instanceof Date ? format.format(cellValue) : cellValue.toString());
                            } else {
                                contentRow.createCell(cellIndex++).setCellValue("");
                            }

                        }else {
                            Object cellValue = subClass.getMethod("get" + newCls[1].substring(0, 1).toUpperCase() + newCls[1].substring(1)).invoke(value);
                            if (cellValue != null) {
                                contentRow.createCell(cellIndex++).setCellValue(cellValue instanceof Date ? format.format(cellValue) : cellValue.toString());
                            } else {
                                contentRow.createCell(cellIndex++).setCellValue("");
                            }
                        }
                    } else {
                        String fieldName = h.substring(0, 1).toUpperCase() + h.substring(1);
                        Method getMethod = cls.getMethod("get" + fieldName);
                        Object value = getMethod.invoke(o);
                        if (value != null) {
                            contentRow.createCell(cellIndex++).setCellValue(value instanceof Date ? format.format(value) : value.toString());
                        } else {
                            contentRow.createCell(cellIndex++).setCellValue("");
                        }
                    }
                }
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        OutputStream os = null;
        try {
            response.reset();
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("gb2312"), "iso-8859-1") + ".xls");
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            os = response.getOutputStream();
            wb.write(os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
